<?php
/**
 * Created by PhpStorm.
 * User: ZhuXueSong
 * Date: 2020-03-18
 * Time: 13:17
 */

namespace App\Http\Controllers\Auth;

use App\Exceptions\ExceptionHelper;
use App\Http\Request;
use App\Constant\CacheConst;
use App\Models\Company\Company;
use Cache;
use App\Models\UserToken;
use Carbon\Carbon;


/**
 * Class User
 * @package App\Http\Controllers\Auth
 */
class User
{
    /**
     * @var \App\Models\User|null
     */
    private $user = null;

    /**
     * @var int
     */
    private $userId    = 0;

    /**
     * @var UserToken
     */
    private $userToken = null;

    private static $static = null;

    /**
     * User constructor.
     * @param bool $throw
     */
    private function __construct(bool $throw = false)
    {
        if ($throw) {
            $this->init();
        } else {
            try {
                $this->init();
            } catch (\Throwable $e) {
            }
        }
    }

    /**
     * 初始化用户信息
     */
    private function init()
    {
        $token  = Request::getUserToken();
        $client = Request::clientType();
        if (empty($token)) { // token不存在，抛出未登录异常
            throw ExceptionHelper::getInstance(ExceptionHelper::USER_NOT_LOGIN);
        }
        $userToken = $this->getUserTokenBy($token);
        $user      = $userToken->user ?? null;
        if (!$userToken) { // token是否真实, 可用来判断账号是否在其他APP登录
            throw ExceptionHelper::getInstance(ExceptionHelper::USER_LOGIN_OTHER);
        }
        if ($user->isLock()) {
            throw ExceptionHelper::getInstance(ExceptionHelper::USER_IS_LOCK);
        }
        if ($userToken->isExpire()) { // token是否过期
            throw ExceptionHelper::getInstance(ExceptionHelper::USER_LOGIN_EXPIRE);
        }
        if (!$user) throw ExceptionHelper::getInstance(ExceptionHelper::USER_NOT_LOGIN);

        $this->userToken = $userToken;
        $this->userId    = $user->id ?? 0;
        $this->user      = $user;
    }

    /**
     * @param bool $throw
     * @return User
     */
    public static function getInstance($throw = true)
    {
        if (!self::$static) {
            self::$static = new self($throw);
        }
        return self::$static;
    }

    /**
     * @return UserToken|null
     */
    public function token()
    {
        return $this->userToken;
    }

    /**
     * 获取登录用户id
     * @return int
     */
    public function userId()
    {
        return $this->userId;
    }

    /**
     * 获取登录用户信息
     * @return \App\Models\User|null
     */
    public function user()
    {
        if (!$this->user) {
            $this->user = $this->userToken->user ?? null;
        }
        return $this->user;
    }

    /**
     * @param $token
     * @return UserToken|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|mixed|object|null
     */
    private function getUserTokenBy($token)
    {
        $cacheKey   = sprintf(CacheConst::CACHE_USER_TOKEN, $token);
        $cacheToken = Cache::get($cacheKey);
        if ($cacheToken && $cacheToken instanceof UserToken) {
            return $cacheToken;
        }
        $userToken = UserToken::getOneByToken($token);
        if ($userToken) { // 缓存14天
            try {
                Cache::set($cacheKey, $userToken, Carbon::now()->addDays(UserToken::TOKEN_EXPIRE_DAYS));
            } catch (\Psr\SimpleCache\InvalidArgumentException $e) {
            }
        }
        return $userToken;
    }
}
